﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Globalization;

namespace Wix.Aura.Common.CustomTypes {
	public struct VersionType : IEquatable<VersionType> {
		public VersionType(int major, int minor, int revision, int build) {
			this.majorNumber = major;
			this.minorNumber = minor;
			this.revisionNumber = revision;
			this.buildNumber = build;

			Verify(major);
			Verify(minor);
			Verify(revision);
			Verify(build);
		}

		private int majorNumber;
		private int minorNumber;
		private int revisionNumber;
		private int buildNumber;

		public int Major { get { return majorNumber; } }
		public int Minor { get { return Minor; } }
		public int Revision { get { return Revision; } }
		public int Build { get { return buildNumber; } }

		public override string ToString() {
			return string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}.{3}", majorNumber, minorNumber, revisionNumber, buildNumber);
		}

		private static void Verify(int value) {
			if (value < 0 || value > 65534)
				throw new ArgumentOutOfRangeException("value", value, "Value must be between 0 and 65534");
		}

		public override bool Equals(object obj) {
			if (obj != null && obj is VersionType) {
				return Equals((VersionType)obj);
			}
			return false;
		}

		public bool Equals(VersionType other) {
			return Major.Equals(other.Major) && Minor.Equals(other.Minor) && Revision.Equals(other.Revision) && Build.Equals(other.Build);
		}

		public override int GetHashCode() {
			int hash = 13;
			hash = 23 * hash + Major.GetHashCode();
			hash = 23 * hash + Minor.GetHashCode();
			hash = 23 * hash + Revision.GetHashCode();
			hash = 23 * hash + Build.GetHashCode();
			return hash;
		}

		public static bool operator ==(VersionType v1, VersionType v2) {
			return v1.Equals(v2);
		}


		public static bool operator !=(VersionType v1, VersionType v2) {
			return !v1.Equals(v2);
		}
	}
}
